import Vue from "vue";
import App from "./App.vue";

import "./plugin/muse-ui";
import "./plugin/directives";
import "./plugin/composition-api";

import { newStore, IStore, STORAGE_KEY } from "./store";
import { routes } from "./plugin/router";
import { Config, mergeOptions } from "./utils/typechecker";
import VueRouter from "vue-router";
import {
	createMode,
	createConf,
	parseMode,
	Select,
	warn,
} from "./utils/helper";

Vue.config.productionTip = false;

import "material-icons/iconfont/filled.css";

import pkg from "../package.json";

class Matable {
	VERSION = pkg.version;
	options: Config[] = [];

	public __vue: any = null;
	public __store: any = null;
	public __router: any = null;

	constructor(public globalConfig?: IStore["globalConfig"]) {}

	/**
	 * @param config 用户的配置
	 */
	add(config: Config | Config[]) {
		if (!Array.isArray(config)) {
			this.options.push(mergeOptions(config));
		} else {
			config.forEach((item) => this.options.push(mergeOptions(item)));
		}
		return this;
	}

	config(config: Config | Config[]) {
		return this.add(config);
	}

	/**
	 * @param target 待渲染节点
	 */
	render(target: string) {
		/**
		 * 在 vuex 中混入配置数据
		 */

		const store = newStore();
		store.state.config = this.options;

		if (window.localStorage.getItem(STORAGE_KEY.TABLE_FULLWIDTH) === null) {
			window.localStorage.setItem(STORAGE_KEY.TABLE_FULLWIDTH, "1");
		}

		if (
			typeof this.globalConfig !== "undefined" &&
			this.globalConfig !== null
		) {
			store.state.globalConfig = {
				...store.state.globalConfig,
				...this.globalConfig,
			};
		}

		const router = new VueRouter({
			mode: "hash",
			routes: !store.state.globalConfig.countdown
				? routes.filter((e) => e.name !== "count-down")
				: routes,
		});

		router.beforeEach((to, from, next) => {
			const index = Number(to.query.index);
			if (0 <= index && index < store.state.config.length) {
				store.state.index = index;
			} else {
				store.state.index = 0;
			}
			next();
		});

		this.__vue = new Vue({
			store,
			router,
			render: (h) => h(App),
		}).$mount(target);

		this.__store = store;
		this.__router = router;

		return this;
	}

	resolveData(conf: Config | string) {
		if (!this.__store === null || !this.__store.state) {
			warn(
				`Only after [render] can method [resolveData] be used`,
				`RESOLVE_DATA::BEFORE_RENDER`
			);
			return null;
		}

		if (!conf) {
			warn(`Missing input param`, `RESOLVE_DATA::MISSING_PARAM`);
			return null;
		}

		const state = this.__store.state.data;
		const config = this.__store.state.config;
		const target = typeof conf === "string" ? conf : conf.data;
		for (let i in config) {
			if (config[i].data === target) {
				return state[i];
			}
		}
		return null;
	}
}

function init(globalConfig?: IStore["globalConfig"]) {
	return new Matable(globalConfig);
}

export { init, parseMode, createMode, createConf, Select };

if (process.env.NODE_ENV === "development") {
	(window as any).Matable = {
		init,
		Select,
		parseMode,
		createMode,
		createConf,
	};
}
